﻿using Newtonsoft.Json.Linq;
using System.Collections.Concurrent;
using System.Text;
using drinking.Api;
using drinking.Helpers;
using drinking.Models;

namespace drinking.Managers
{
    public class UserManager
    {

        /// <summary>
        /// 本地线程变量，当前线程的变量，该变量对其他线程而言是封闭且隔离的
        /// 在进行对象跨层传递的时候，使用ThreadLocal可以避免多次传递，打破层次间的约束
        /// </summary>
        public static ThreadLocal<Customer> CurrCustomer { get; private set; } = new ThreadLocal<Customer>();

        /// <summary>
        /// 微信登录用户缓存容器，键：token  值 Customer对象
        /// </summary>
        public static ConcurrentDictionary<string, Models.Customer> CacheCustomers { get; private set; } = new ConcurrentDictionary<string, Models.Customer>();



        public static Customer InitCustomerByOpenid(string opneid_code)
        {
            string openid = WxManager.GetUserOpenId(opneid_code);
            if (openid == null)
            {
                throw new Exception("微信登录code失效");
            }
            var db = new DBContext().Db;
            Customer customer = db.Queryable<Customer>().Where(c => c.Openid == openid).First();
            if (customer == null) // 首次登录
            {
                customer = new Customer()
                {
                    Phone = "",
                    CreateTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                    CustomerName = $"vip",
                    Token = Guid.NewGuid().ToString("N"),
            };
                customer.CustomerId = db.Insertable(customer).ExecuteReturnIdentity();
            }
            else
            {
                // 非首次登录 token 过期
                customer.Token = Guid.NewGuid().ToString("N");
                db.Updateable(customer).UpdateColumns(c => new { customer.CustomerId }).ExecuteCommand();
            }
            
            CacheCustomers.TryAdd(customer.Token, customer);
            return customer;
        }


        /// <summary>
        /// 循环定时任务：用户一周之内没有使用过小程序，那么将该用户的数据从缓存中清除，下次打开小程序将重新授权登录
        /// 这个定时任务在启动的时候开始执行，间隔1分钟执行1次
        /// </summary>
        public static Timer UserCacheRefreshTimer
        {
            get; private set; 
        } 
            = new Timer((obj) =>
        {
            List<String> deleteKeys = new List<string>();
            foreach (var item in CacheCustomers)
            {
                // 超过 7 天未请求接口， 缓存中清除token, 前端存储的token 失效
                if ((DateTime.Now - item.Value.LastAccessTime).TotalMinutes > 60 * 24 * 7)
                {
                    // 字典不能边遍历边删除，把要删除的key存储起来，遍历完成之后再删除
                    deleteKeys.Add(item.Key);
                }
            }
            foreach (var item in deleteKeys)
            {
                CacheCustomers.Remove(item, out var v);
            }
        });


    }
}
